﻿
/* Init.cs - the initialization system for NoobOS
 * Copyright (C) 2012 NoobOS
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cosmos.Core;
using Cosmos.Hardware;
using Cosmos.Hardware.BlockDevice;
using Cosmos.System.Filesystem.Listing;
using NoobOS.FileSystem.Physical;
using NoobOS.FileSystem.NoobFileSystem;
using NoobOS.FileSystem.Physical.Drivers;
namespace NoobOS
{
    class Init
    {
        public static bool Error = false;

        private static PrimaryPartition workPartition = null;

        /// <summary>
        /// The Init of NoobOS System.
        /// </summary>
        public static int RunInit()
        {
            #region Version
            Helper.WriteLine("NoobOS 0.5.1 Alpha Booting...", ConsoleColor.DarkMagenta);
            #endregion
            #region Memory
            Helper.WriteLine("Checking Memory...");
            uint mem = CPU.GetAmountOfRAM();
            Helper.Write("Memory: " + (mem + 2) + " MB ");
            Helper.WriteLine("OK", ConsoleColor.Green);
            #endregion
            #region Disks and Partitions
            Helper.WriteLine("Getting Disks...");
            IDE[] IDEs = IDE.Devices.ToArray();
            Helper.WriteLine("Number of IDE disks: " + IDEs.Length);
            Helper.WriteLine("Looking for valid partitions...");
            for (int i = 0; i < IDEs.Length; i++)
            {
                PrimaryPartition[] parts = IDEs[i].PrimaryPartitions;
                for (int j = 0; j < parts.Length; j++)
                {
                    if (parts[j].Infos.SystemID == 0xFA)
                    {
                        workPartition = parts[j];
                    }
                }
            }
            //#warning Revert to == null!!!
            if (workPartition == null)
            {
                DiskHandler.CreatePartitions(IDEs);
                Helper.WriteLine("The machine needs to be restarted.");
                return 2;
            }
            Helper.Done();
            #endregion
            #region FileSystem
            Helper.Write("Checking FileSystem... ");
            NoobFileSystem fs;
            try
            {
                fs = new NoobFileSystem(workPartition);
                NoobFileSystem.AddMapping("/", fs);
                Helper.Done();
            }
            catch (Exception ex)
            {
                Helper.Error("Error!" + ex.Message);
                Error = true;
            }
            #endregion
            
            return 0;
        }
        private static NoobDirectory sf;
        private static void CreateDirectoryAndVerify(string directory)
        {
            NoobFileSystem.mFS.Root.AddDirectory(directory);
            sf = NoobFileSystem.mFS.Root.GetDirectoryByName(directory);
            if (sf == null)
            {
                Helper.Error("Cannot create required files, aborting creation of " + directory);
                throw new Exception("Failed creation of directories.");
            }
        }
        private static void CreateFileAndVerify(string file, string directory)
        {
            NoobDirectory dir = NoobFileSystem.mFS.Root.GetDirectoryByName(directory);
            if (dir != null)
            {
                dir.AddFile(file);
                NoobFile nf = dir.GetFileByName(file);
                if (nf == null)
                {
                    throw new Exception("Could not create!");
                }

            }
            else
            {
                throw new ArgumentException("Bad directory");
            }
        }
        private static void CreateFileWithContentsAndVerify(string file, string directory, byte[] data)
        {
            NoobDirectory dir = NoobFileSystem.mFS.Root.GetDirectoryByName(directory);
            if (dir != null)
            {
                dir.AddFile(file);
                NoobFile nf = dir.GetFileByName(file);
                if (nf == null)
                {
                    throw new Exception("Could not create!");
                }
                else
                {
                    nf.WriteAllBytes(data);
                }

            }
            else
            {
                throw new ArgumentException("Bad directory");
            }
        }
        private static void CreateFileWithContentsAndVerify(string file, string directory, string data)
        {
            NoobDirectory dir = NoobFileSystem.mFS.Root.GetDirectoryByName(directory);
            if (dir != null)
            {
                dir.AddFile(file);
                NoobFile nf = dir.GetFileByName(file);
                if (nf == null)
                {
                    throw new Exception("Could not create!");
                }
                else
                {
                    nf.WriteAllText(data);
                }

            }
            else
            {
                throw new ArgumentException("Bad directory");
            }
        }
    }

}
